<template>
    <div class="p-4 space-y-6 rounded-lg">
        <!-- 显示录音时间 -->
        <div class="text-center text-lg font-bold text-gray-700">
            录音时间：<span class="text-red-500">{{ formattedTime }}</span>
        </div>

        <!-- Canvas 用于显示波形 -->
        <canvas ref="canvas" class="w-full h-36 rounded-mdx"></canvas>

        <!-- 控制按钮 -->
        <div class="flex justify-center space-x-4">
            <!-- 开始录音按钮 -->
            <button v-if="!isRecording" @click="startRecording"
                class="px-6 py-2 bg-blue-500 text-white font-bold rounded-lg shadow transition hover:bg-blue-600">
                开始录音
            </button>

            <!-- 停止录音按钮 -->
            <button v-if="isRecording" @click="stopRecording"
                class="px-6 py-2 bg-red-500 text-white font-bold rounded-lg shadow transition hover:bg-red-600">
                停止录音
            </button>

            <!-- 播放录音按钮 -->
            <button v-if="!isRecording" @click="playRecording"
                class="px-6 py-2 bg-green-500 text-white font-bold rounded-lg shadow transition hover:bg-green-600">
                播放录音
            </button>

            <!-- 结束录音按钮 -->
            <button v-if="!isRecording" @click="confirmEndRecording"
                class="px-6 py-2 bg-gray-500 text-white font-bold rounded-lg shadow transition hover:bg-gray-600">
                结束录音
            </button>
        </div>
    </div>
</template>

<script setup>
    import { ref, onMounted } from 'vue';
    import { ElMessage, ElMessageBox } from 'element-plus';
    import 'element-plus/es/components/message/style/css';
    import 'element-plus/es/components/message-box/style/css';
    import Recorder from 'js-audio-recorder';

    let recorder = null;
    let animationFrameId = null;
    let canvasContext = null;
    let audioBlob = null;
    const canvasWidth = 400;
    const canvasHeight = 150;

    const canvas = ref(null);
    const isRecording = ref(false);
    const recordingTime = ref(0);
    const timer = ref(null);
    const formattedTime = ref('00:00');

    const emit = defineEmits(['recordingEnded']);

    const setupCanvas = () => {
        if (canvas.value) {
            canvas.value.width = canvasWidth;
            canvas.value.height = canvasHeight;
            canvasContext = canvas.value.getContext('2d');
            clearCanvas();
        }
    };

    const clearCanvas = () => {
        if (canvasContext) {
            canvasContext.fillStyle = 'white';
            canvasContext.fillRect(0, 0, canvasWidth, canvasHeight);
        }
    };

    const formatTime = (time) => {
        const minutes = Math.floor(time / 60)
            .toString()
            .padStart(2, '0');
        const seconds = (time % 60).toString().padStart(2, '0');
        return `${minutes}:${seconds}`;
    };

    const startRecording = () => {
        recorder = new Recorder();

        Recorder.getPermission()
            .then(() => {
                isRecording.value = true;
                recordingTime.value = 0;
                formattedTime.value = '00:00';

                timer.value = setInterval(() => {
                    recordingTime.value++;
                    formattedTime.value = formatTime(recordingTime.value);
                }, 1000);

                animateWaveform();
                console.log('开始录音');
                recorder.start();
            })
            .catch((error) => {
                console.error('录音权限被拒绝:', error);
            });
    };

    const stopRecording = () => {
        if (recorder) {
            audioBlob = recorder.getWAVBlob();
            console.log("录音停止，获取的音频 Blob:", audioBlob);
            recorder.stop();
            cancelAnimationFrame(animationFrameId);
            clearCanvas();
            isRecording.value = false;

            if (timer.value) {
                clearInterval(timer.value);
                timer.value = null;
            }
        }
    };

    const playRecording = () => {
        if (!recorder || !recorder.getWAVBlob()) {
            return ElMessage.error("未录音");
        }
        isRecording.value = false;
        if (recorder) {
            recorder.stop();
            recorder.play();
        }
    };

    const endRecording = () => {
        stopRecording();
        recorder.downloadWAV(`${Date.now()}`);
        console.log("录音时间长:", recorder.getPlayTime());
        emit('recordingEnded', recorder.getWAVBlob());
        resetRecordingData();
    };

    const animateWaveform = () => {
        const draw = () => {
            if (!recorder || !isRecording.value) {
                return;
            }

            try {
                const dataArray = recorder.getRecordAnalyseData();
                if (dataArray) {
                    clearCanvas();

                    const gradient = canvasContext.createLinearGradient(0, 0, canvasWidth, 0);
                    gradient.addColorStop(0, 'red');
                    gradient.addColorStop(0.33, 'orange');
                    gradient.addColorStop(0.66, 'blue');
                    gradient.addColorStop(1, 'green');

                    canvasContext.lineWidth = 2;
                    canvasContext.strokeStyle = gradient;

                    canvasContext.beginPath();

                    const sliceWidth = canvasWidth / dataArray.length;
                    let x = 0;

                    for (let i = 0; i < dataArray.length; i++) {
                        const value = dataArray[i];
                        const y = canvasHeight / 2 + (value / 255.0) * (canvasHeight / 2 - 10);

                        if (i === 0) {
                            canvasContext.moveTo(x, y);
                        } else {
                            const previousX = x - sliceWidth;
                            const previousY = canvasHeight / 2 + (dataArray[i - 1] / 255.0) * (canvasHeight / 2 - 10);
                            const controlX = (previousX + x) / 2;
                            const controlY = (previousY + y) / 2;
                            canvasContext.quadraticCurveTo(controlX, controlY, x, y);
                        }

                        x += sliceWidth;
                    }

                    canvasContext.stroke();
                }
            } catch (error) {
                console.error('获取录音数据时出错:', error);
            }

            animationFrameId = requestAnimationFrame(draw);
        };

        draw();
    };

    const resetRecordingData = () => {
        if (recorder) {
            recorder.stop();
            recorder = null;
        }
        if (timer.value) {
            clearInterval(timer.value);
            timer.value = null;
        }

        isRecording.value = false;
        recordingTime.value = 0;
        formattedTime.value = '00:00';
        audioBlob = null;

        clearCanvas();
        console.log("所有录音数据已重置");
    };

    // 确认结束录音
    const confirmEndRecording = () => {
        if (!recorder) {
            emit('recordingEnded');
            return
        }
        ElMessageBox.confirm(
            '确定要结束录音吗？此操作将保存至电脑中。选择取消则放弃该录音',
            '确认操作',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            }
        )
            .then(() => {
                endRecording();
                ElMessage({
                    type: 'success',
                    message: '录音已结束',
                });
            })
            .catch(() => {
                emit('recordingEnded');
            });
    };

    onMounted(() => {
        setupCanvas();
    });
</script>